<template>
    <el-dialog v-dialogDrag v-bind="$attrs" :title="`${title}导入`" v-on="$listeners" :close-on-press-escape="false" custom-class="common-dialog" width="1000px">
        <div class="common-import__container">
            <div class="upload-wrapper">
                <el-upload class="import-uploader" ref="importUploader" 
                    :action= "uploadUrl" 
                    :accept="fileAccept" 
                    :limit="1" 
                    :headers="headers"
                    :data="params"
                    :on-change="handleFileChange"
                    :on-remove="handleFileChange"
                    :on-exceed="handleExceed" 
                    :before-upload="handleBeforeUpload" 
                    :before-remove="handleBeforeRemove"
                    :on-success="handleSuccess"
                    :auto-upload="true"
                    >
                    <el-button slot="trigger" size="small" type="primary">上传数据文件</el-button>
                    <!-- <el-button style="margin-left: 10px;" size="small" type="success" :disabled="uploadDisabled" @click="handleUpload">上传数据文件</el-button> -->
                    <el-button style="margin-left: 10px;" size="small" type="warning" :disabled="importDisabled" @click="handleImport">开始导入</el-button>
                    <div slot="tip" class="el-upload__tip">
                        <div class="common-import-tip__wrapper">
                            <div>
                                <el-radio-group v-model="fileType" size="mini">
                                    <el-radio-button label="excel">Excel文件</el-radio-button>
                                    <el-radio-button label="json">JSON文件</el-radio-button>
                                </el-radio-group>
                            </div>
                            <div style="line-height:35px;">只能上传{{fileAccept}}文件,且不超过 {{fileSizeFormat}} <span v-show="fileType==='excel'">,导入数据模板请下载 [<el-button type="text" size="mini" @click="downloadTemplete">{{title}}数据导入模板</el-button>]</span></div>
                            <el-checkbox v-model="updateSupport" > 是否覆盖重复数据</el-checkbox>
                        </div>
                    </div>
                </el-upload>
            </div>
            <div class="import-wrapper">
                <div class="import-info" v-if="importFlag">
                    <div class="info">
                        <span>总计:{{importData.total}}条 已导入:{{importData.imported}}条 未导入:{{importData.unImport}}条</span>
                        <span>导入成功:{{importData.success}}条 | 导入失败:{{importData.failure}}条</span>
                    </div>
                    <div class="progress">
                        <el-progress :percentage="importData.progress" :text-inside="true" :stroke-width="16"></el-progress>
                    </div>
                </div>
                <div class="import-result">
                    <ul class="import-result-list" v-if="importData.result.length>0">
                        <li v-for="item in importData.result" :key="item.id">
                            <div class="name">{{item.title}}</div>
                            <div class="dot"></div>
                            <div class="result">
                                <el-tag :type="importStatusColor(item.status)" size="mini">
                                    <i :class="importStatusIcon(item.status)"></i> {{item.status|importStatus}}
                                </el-tag>
                            </div>
                            <div class="opts">
                                <el-button type="text" size="mini" v-if="item.status===2" icon="el-icon-refresh" @click="handleRetry(item)"></el-button>
                            </div>
                        </li>
                    </ul>
                    <el-empty description="暂无数据" :image="require('@/assets/images/import.png')" :image-size="80" v-else></el-empty>
                </div>
            </div>
        </div>
    </el-dialog>
</template>
<script>
import request from '@/utils/request'
import {isNumberStr} from "@/utils/index"
import {initWebSocket} from "@/utils/websocket"
import { getToken } from "@/utils/auth";

const initImportData = {
    progress: 0,
    total: 0,
    imported: 0,
    unImport: 0,
    success: 0,
    failure: 0,
    result: []
}

export default {
    name: "CommonImport",
    props: {
        options: {
            type: Object,
            default: ()=>{}
        },
        fileSize: {
            type: String,
            default: "50MB"
        },
        title: {
            type: String,
            default: "数据导入"
        }
    },
    data() {
        return {
            uploadUrl: process.env.VUE_APP_BASE_API+"/system/openapi/readData",
            dialogVisible: this.open,
            fileType: "excel",    //目前先支持xls 和 json两种格式
            uploadFile: null,
            importFlag: false,
            uploadDisabled: true,  //是否可上传
            importDisabled: true,  //是否可导入
            updateSupport: 0, //是否覆盖重复数据
            headers: { Authorization: "Bearer " + getToken(),
            clientid: process.env.VUE_APP_CLIENT_ID
             },
            importData: {...initImportData},
            params: {
                fileType: this.fileType
            }
        }
    },
    filters: {
        importStatus(value) {
            const status = {
                0: '待导入',
                1: '成功',
                2: '失败'
            }
            return status[value]
        },
    },
    methods: {
        downloadTemplete() {
            if(this.options.templateUrl){
                this.download(this.options.templateUrl, {}, `${title}导入模板_${new Date().getTime()}.xlsx`)
            }
        },
        handleClose(done) {
            // this.$emit("update:visible", false);
            // this.$emit("closed");
            done();
        },
        async handleBeforeRemove(file, fileList){
            const res = await this.$confirm(`确定移除 ${ file.name }？`);
            if(res){
                this.importData = {...initImportData};
                this.importFlag = false
                return true;
            }else{
                return false;
            }
        },
        handleBeforeUpload(file) {
            const fileSuffix = file.name.substring(file.name.lastIndexOf("."))
            if (this.fileAccept.indexOf(fileSuffix) === -1) {
                this.$message.error(`上传文件只能是 ${this.fileAccept} 格式`)
                return false
            }
            
            if (!this.validFileSize(file.size)) {
                this.$message.error(`上传文件大小不能超过 ${this.fileSizeFormat}`)
                return false
            }
            this.params.fileType = this.fileType;
        },
        handleSuccess(res, file, fileList){
            this.importData = res.data
            this.uploadFile = file.raw
            this.importFlag = true
            this.importDisabled = false
        },
        validFileSize(size){
            let _fileSizeLimit = this.fileSize.toUpperCase();
            //如果是纯数字，代表字节数
            if(isNumberStr(_fileSizeLimit)){
                return size < _fileSizeLimit;
            }
            //如果带有K\KB
            if(_fileSizeLimit.indexOf("K")!=-1 || _fileSizeLimit.indexOf("KB")!=-1){
                _fileSizeLimit = _fileSizeLimit.replace(/[^0-9]/gi, "");
                return size / 1024 < _fileSizeLimit;
            }
            
            //如果带有M\MB
            if(_fileSizeLimit.indexOf("M")!=-1 || _fileSizeLimit.indexOf("MB")!=-1){
                _fileSizeLimit = _fileSizeLimit.replace(/[^0-9]/gi, "");
                return size / 1024 / 1024 < _fileSizeLimit;
            }
            //如果带有G\GB
            if(_fileSizeLimit.indexOf("G")!=-1 || _fileSizeLimit.indexOf("GB")!=-1){
                _fileSizeLimit = _fileSizeLimit.replace(/[^0-9]/gi, "");
                return size / 1024 / 1024 / 1024 < _fileSizeLimit;
            }
        },
        handleFileChange(file, fileList){
            this.uploadDisabled = !fileList.length>0;
        },
        handleExceed(files, fileList) {
            this.$message.warning(`当前限制选择 1 个文件，请删除后继续上传`)
        },
        handleUpload() {
            this.$refs.importUploader.submit()
        },
        handleImport() {
            if (this.uploadFile == null) {
                this.$message.error("数据文件丢失，请重新选择文件并上传")
                return false
            }
            let fd = new FormData()
            fd.append("file", this.uploadFile)
            fd.append("updateSupport", this.updateSupport)
            fd.append("fileType",this.fileType)
            request({
                url: this.options.importRequest,
                method: "post",
                data: fd
            }).then(res => {

                // this.$message.success('导入完成!')
            })
        },
        getImportData(msg) {
            if (msg.indexOf('result') !== -1) {
                let jsonResult = JSON.parse(msg)
                // console.log("原始=====>", this.importData)
                this.importData = this.deepMerge(this.importData, jsonResult)
                // console.log("获取websocket数据=====>", this.importData)
                if (this.importData.unImport === 0) {
                    this.$message.success('导入完成!')
                    this.importDisabled = true;
                }
            } else {
                console.log(msg)
            }
        },
        handleRetry(item){

        },
        handleRetryAll(){

        },
        deepMerge(obj1, obj2) {
            let key
            for (key in obj2) {
                // 如果target(也就是obj1[key])存在，且是对象的话再去调用deepMerge，否则就是obj1[key]里面没这个对象，需要与obj2[key]合并
                obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ? this.deepMerge(obj1[key], obj2[key]) : (obj1[key] = obj2[key])
            }
            return obj1
        }
    },
    watch: {

    },
    cteated() {

    },
    mounted() {
        let protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'
        initWebSocket(protocol + window.location.host + process.env.VUE_APP_BASE_API + "/resource/websocket",(e)=>{
            this.getImportData(e.data)
        });
    },
    computed: {
        fileAccept(){
            return this.fileType==="excel"?".xls,.xlsx":".json";
        },
        fileSizeFormat(){
            return isNumberStr(this.fileSize)? this.fileSize+" Byte" : this.fileSize
        },
        importStatusColor() {

            return (value) => {
                const status = {
                    0: 'info',
                    1: 'success',
                    2: 'danger'
                }
                return status[value]
            }
        },
        importStatusIcon(value) {
            return (value) => {
                const status = {
                    0: 'el-icon-warning-outline',
                    1: 'el-icon-circle-check',
                    2: 'el-icon-circle-close'
                }
                return status[value]
            }
        }
    },
}
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body{
    padding-top: 15px;
    padding-bottom: 20px;
}
.import-uploader {
    :deep(.el-upload-list__item) {
        &:first-child {
            margin-top: 0;
        }
    }
    .el-upload__tip {
        margin-top: 0;
    }
    .common-import-tip__wrapper{
        margin-top: 10px;
        border-top:1px solid #f3f3f3;
        padding-top:10px;
    }
}
.import-wrapper {
    margin-top: 10px;
    .import-info {
        margin-bottom: 10px;
        .info {
            display: flex;
            justify-content: space-between;
        }
        .progress {
            margin-top: 10px;
        }
    }
    .import-result {
        padding: 10px;
        overflow-x: hidden;
        overflow-y: auto;
        height: 500px;
        background-color: #f3f3f3;
        border:1px solid #eee;
        position: relative;
        .el-empty {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
        }
        .import-result-list {
            li {
                // line-height: 30px;
                background-color: #fff;
                display: flex;
                justify-content: space-between;
                padding: 3px 10px;
                margin-bottom: 1px;
                align-items: center;
                .dot {
                    height: 1px;
                    flex: 1;
                    border-bottom: 1px dotted #aaa;
                    margin: 0 10px;
                }
                .opts{
                    margin-left:10px;
                }
                &:hover {
                    background-color: #fafafa;
                }
            }
        }
    }
}
</style>
